﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Reflection;
using System.Threading;
using System.IO;
using System.Xml;
using System.Data.SqlClient;
using System.Timers;
using System.Net;
using log4net;

namespace LogMonitorHost
{
    public partial class LogHost : ServiceBase
    {

        //日志记录
        ILog log;

        static string conString = ConfigurationManager.ConnectionStrings["SecLogConnectionString"].ToString();
        


        //初始化ID，用来作为查找的范围。如果是初始化，就已上一日的某个时点为查询点。
        int lastId = 0;


        //发送邮件的timer
        System.Timers.Timer sendEmailTimer;


        public LogHost()
        {
            InitializeComponent();

            log4net.Config.XmlConfigurator.Configure();
            log = LogManager.GetLogger(typeof(LogHost));
            log.Info("LogHost运行。");
        }

        protected override void OnStart(string[] args)
        {
            log.Info("LogHost 服务启动。");
            int timerInterval = int.Parse(System.Configuration.ConfigurationManager.AppSettings["timerInterval"].ToString());
            log.Info("timerInterval = "+timerInterval.ToString());

            //准备采用新方式来进行查询。
            if (lastId == 0)
            {
                lastId = findLastId();

            }
            log.Info("lastId = "+lastId.ToString());

            //if (oldid != -1)
            //{
            //    sendReportByEmail();
            //}


            sendReportByEmail();

            sendEmailTimer = new System.Timers.Timer();
            sendEmailTimer.Elapsed += new ElapsedEventHandler(OnEmailTimerTickedEvent);
            sendEmailTimer.Interval = timerInterval; 
            // sendEmailTimer.Enabled = true;
            sendEmailTimer.Start();

        }


        /// <summary>
        /// 查找上次的ID
        /// </summary>
        /// <returns></returns>
        private int findLastId()
        {
            int returnInt = 0;
            try
            {
                int currTime = DateTime.Now.Hour;
                log.Info("currTime =" +currTime.ToString ());
                string currDate ="";

                //如果初始的时间是9时以后，就发出当天的信息即可。
                if (currTime > 9)
                {
                    currDate = DateTime.Now.ToShortDateString();              
                }
                else
                {
                    currDate = DateTime.Now.AddDays(-1).ToShortDateString();
                }
                string selectstring = "SELECT top 1 [id] FROM [seclog].[dbo].[logMessage]  where logDate = '" + currDate + "' order by id";

                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);


                DataRow singleDataRow = selectResultDS.Tables[0].Rows[0];
                returnInt = int.Parse(singleDataRow["id"].ToString());

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
                return -1;
            }

            return returnInt;
        }


        /// <summary>
        /// 查找上次的ID
        /// </summary>
        /// <returns></returns>
        private int findCurrentId()
        {
            int returnInt = 0;
            try
            {
                
                string selectstring = "SELECT top 1 [id] FROM [seclog].[dbo].[logMessage]  order by id desc";

                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);


                DataRow singleDataRow = selectResultDS.Tables[0].Rows[0];
                returnInt = int.Parse(singleDataRow["id"].ToString());

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
                return -1;
            }

            return returnInt;
        }


        /// <summary>
        /// 根据数据库信息发送
        /// </summary>
        private void sendReportByEmail()
        {
            try
            {
                int currentID = findCurrentId();
                string selectstring = "SELECT [id], [userName], [Email] FROM [seclog].[dbo].[UserInformation]";

                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);


                foreach (DataRow row in selectResultDS.Tables[0].Rows)
                {
                    int userID = int.Parse(row["id"].ToString().Trim());
                    string userName = row["userName"].ToString().Trim();
                    string userEmail = row["Email"].ToString().Trim();

                    string reportMessage = buildReportMessage(userID, userName, lastId);
                    string sendTitle = "服务器连接情况报告" + DateTime.Now.ToString();

                    log.Info(reportMessage);
                    if (!Tools.MailHelper.SendEmail(userEmail, sendTitle, reportMessage))
                    {
                        log.Error("发送邮件失败，请检查设置。");
                    }


                }
                lastId = currentID;
                log.Info(lastId.ToString());

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
            }


        }

        protected override void OnStop()
        {
            sendEmailTimer.Stop();
            log.Info("LogHost 服务停止。");
        }


        /// <summary>
        /// 定时器运行。
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void OnEmailTimerTickedEvent(object source, ElapsedEventArgs e)
        {
            sendReportByEmail();
            
        }


        /// <summary>
        /// 根据用户ID创建报告信息
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        private string buildReportMessage(int userID, string userName,int lastId)
        {
            if (userID < 1)
                userID = 1;

            string queryHost = "SELECT [id],[Host],[LastLiveTime],[OrderID] FROM [seclog].[dbo].[HostLiveMessage]  where id in ( select hostid from [seclog].[dbo].[UserHostMapping] where userid = " + userID + ") order by orderid";
            string sendMessage = "尊敬的" + userName + "：您好，以下是您负责的服务器的有关情况。<br><br><br>";

            //该时间用来判断是否死机。
            DateTime lastDt = DateTime.Now.AddMinutes(-15);
            try
            {
                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(queryHost, conString);

                int i = 0;
                foreach (DataRow row in selectResultDS.Tables[0].Rows)
                {
                    i++;
                    DateTime dt = DateTime.Parse(row["LastLiveTime"].ToString());
                    string hostName = row["Host"].ToString().ToUpper().Trim();
                    sendMessage += "<font color=\"red\">" + hostName + "</font> 最近一次的链接时间是：" + row["LastLiveTime"].ToString();
                    if (lastDt > dt)
                    {
                        sendMessage += "<font color=\"red\">系统有问题！！！" + "</font><br>";
                    }
                    else
                    {
                        sendMessage += "<font color=\"green\">系统正常。" + "</font><br>";
                    }
                    sendMessage += loginServerInformation(hostName,lastId);
                    sendMessage += errorServerInformation(hostName,lastId);
                    sendMessage += "<br>";
                }


                if (i > 0)
                {
                    
                }
                else
                {
                    log.Info("没有查询到信息。");
                }

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
            }

            return sendMessage;
        }

        /// <summary>
        /// 发送Report信息给用户。
        /// </summary>
        private void sendReportByEmailOld()
        {
            string sendMessage = "尊敬的用户：你好，以下是服务器的报告情况。<br><br>";
            string sendTitle = "服务器连接情况报告"+ DateTime.Now.ToString ();
            DateTime lastDt = DateTime.Now.AddMinutes(-15);

            try
            {
                string selectstring = "SELECT [host], [lastlivetime] FROM [seclog].[dbo].[HostLiveMessage] order by orderid";
                
                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);

                int i = 0;
                foreach (DataRow row in selectResultDS.Tables[0].Rows)
                {
                    i++;
                    DateTime dt = DateTime.Parse(row["lastlivetime"].ToString());
                    string hostName = row["host"].ToString().ToUpper().Trim();
                    sendMessage += "<font color=\"red\">" + hostName + "</font> 最近一次的链接时间是：" + row["lastlivetime"].ToString();
                    if (lastDt > dt)
                    {
                        sendMessage += "<font color=\"red\">系统有问题！！！" + "</font><br>";
                    }
                    else
                    {
                        sendMessage += "<font color=\"green\">系统正常。" + "</font><br>";
                    }
                    sendMessage += loginServerInformation(hostName,lastId );
                    sendMessage += errorServerInformation(hostName, lastId);
                    sendMessage += "<br>";
                }
                

                if (i > 0)
                {
                    log.Info(sendMessage);
                    if (!Tools.MailHelper.SendEmail("test@admin.com",sendTitle, sendMessage))
                    {
                        log.Error("发送邮件失败，请检查设置。");
                    }
                }
                else
                {
                    log.Info("没有查询到信息。");
                }

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 查找最近的Error信息。
        /// </summary>
        /// <param name="hostName"></param>
        /// <returns></returns>
        private string errorServerInformation(string hostName, int lastId)
        {
            int i = 0;
            string returnInformation = "最近一段时间服务器的Error情况是：";
            try
            {
                
                string selectstring = "SELECT [id] FROM [seclog].[dbo].[logMessage]  where logtype = 'error' and logsource  <> 'w32time' and logmachine = '" + hostName + "' and id >= " + lastId;
                log.Info(selectstring);
                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);


                i = selectResultDS.Tables[0].Rows.Count;


                if (i > 0)
                {
                    returnInformation += "此期间发生Error事件：<font color=\"red\">" + i.ToString() + "</font>次，请检查是否严重。<br>";
                }
                else
                {
                    returnInformation += "此期间没有发生Error事件。<br>";
                }

            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
            }

            return returnInformation;
        }


        /// <summary>
        /// 查找有关的登录情况，重点在远程控制和控制台登录信息。
        /// </summary>
        /// <param name="hostName"></param>
        /// <returns></returns>
        private string loginServerInformation(string hostName,int lastId)
        {
            int i = 0;
            string logmonitorWebSiteQuery = System.Configuration.ConfigurationManager.AppSettings["logmonitorWebSite"].ToString();
            string returnInformation = "最近一段时间服务器的登录情况是：";
            try
            {

                string selectstring = "SELECT [id],[logName],[logMachine],[logType],[eventID],[user],[logDate],[logTime]  FROM [seclog].[dbo].[logMessage]  where ( logmessage like '%登录类型:_10%' or logmessage like '%登录类型:__10%' ) and eventid = '528' and logmachine = '" + hostName + "' and id >= " + lastId + " order by [logMachine]";

                log.Info(selectstring);
                DataSet selectResultDS = SqlHelper.SqlHelper.GetDataSet(selectstring, conString);


                foreach (DataRow row in selectResultDS.Tables[0].Rows)
                {
                    i++;
                    returnInformation += "<br><font color=\"red\">" + row["user"].ToString() + "</font> 时间是：" + row["logDate"].ToString() + " " + row["logTime"].ToString() + " <a href=\"" + logmonitorWebSiteQuery + "LogDetailView.aspx?queryID=" + row["id"].ToString() + "\" target=\"_blank\">点击查看</a> \r\n";
                }


                if (i < 1)
                {
                    returnInformation += "没有人登录此服务器。<br>";
                }
                else
                {
                    returnInformation += "<br>";
                }
              
            }
            catch (Exception ex)
            {
                log.Error(ex.ToString());
            }

            return returnInformation;
        }





    }
}
